/**
 * Audio File Generator for Pomodoro Timer
 * This script creates simple audio files using Web Audio API and saves them as WAV files
 */

// Audio configurations for different sound types
const audioConfigs = {
    bell: {
        frequencies: [800, 1000, 800],
        durations: [0.3, 0.2, 0.4],
        volumes: [0.4, 0.3, 0.4],
        waveType: 'sine',
        gap: 0.1
    },
    chime: {
        frequencies: [523.25, 659.25, 783.99], // C5, E5, G5
        durations: [0.8, 0.8, 1.2],
        volumes: [0.3, 0.25, 0.3],
        waveType: 'triangle',
        gap: 0.2
    },
    ding: {
        frequencies: [1200, 1500],
        durations: [0.15, 0.25],
        volumes: [0.35, 0.25],
        waveType: 'sine',
        gap: 0.05
    },
    notification: {
        frequencies: [600, 800, 1000, 800],
        durations: [0.2, 0.2, 0.3, 0.3],
        volumes: [0.3, 0.35, 0.4, 0.3],
        waveType: 'square',
        gap: 0.1
    },
    gentle: {
        frequencies: [440, 554.37], // A4, C#5
        durations: [1.0, 1.5],
        volumes: [0.2, 0.15],
        waveType: 'sine',
        gap: 0.3,
        fadeIn: 0.3,
        fadeOut: 0.5
    },
    success: {
        frequencies: [523.25, 659.25, 783.99, 1046.50], // C5, E5, G5, C6
        durations: [0.2, 0.2, 0.2, 0.6],
        volumes: [0.3, 0.35, 0.4, 0.45],
        waveType: 'triangle',
        gap: 0.05
    }
};

/**
 * Generate audio buffer for a given configuration
 */
function generateAudioBuffer(audioContext, config) {
    const { frequencies, durations, volumes, waveType = 'sine', gap = 0, fadeIn = 0.1, fadeOut = 0.1 } = config;
    
    // Calculate total duration
    const totalDuration = durations.reduce((sum, duration, index) => {
        return sum + duration + (index < durations.length - 1 ? gap : 0);
    }, 0);
    
    const sampleRate = audioContext.sampleRate;
    const bufferLength = Math.ceil(totalDuration * sampleRate);
    const buffer = audioContext.createBuffer(1, bufferLength, sampleRate);
    const channelData = buffer.getChannelData(0);
    
    let currentSample = 0;
    
    frequencies.forEach((frequency, index) => {
        const duration = durations[index] || durations[0];
        const volume = volumes[index] || volumes[0] || 0.3;
        const samplesCount = Math.ceil(duration * sampleRate);
        
        const fadeInSamples = Math.ceil(fadeIn * sampleRate);
        const fadeOutSamples = Math.ceil(fadeOut * sampleRate);
        
        for (let i = 0; i < samplesCount; i++) {
            const t = i / sampleRate;
            let amplitude = volume;
            
            // Apply fade in
            if (i < fadeInSamples) {
                amplitude *= i / fadeInSamples;
            }
            // Apply fade out
            else if (i > samplesCount - fadeOutSamples) {
                amplitude *= (samplesCount - i) / fadeOutSamples;
            }
            
            // Generate waveform
            let sample = 0;
            switch (waveType) {
                case 'sine':
                    sample = Math.sin(2 * Math.PI * frequency * t) * amplitude;
                    break;
                case 'triangle':
                    sample = (2 / Math.PI) * Math.asin(Math.sin(2 * Math.PI * frequency * t)) * amplitude;
                    break;
                case 'square':
                    sample = Math.sign(Math.sin(2 * Math.PI * frequency * t)) * amplitude;
                    break;
                case 'sawtooth':
                    sample = (2 * (frequency * t - Math.floor(frequency * t + 0.5))) * amplitude;
                    break;
            }
            
            if (currentSample + i < bufferLength) {
                channelData[currentSample + i] = sample;
            }
        }
        
        currentSample += samplesCount + Math.ceil(gap * sampleRate);
    });
    
    return buffer;
}

/**
 * Convert AudioBuffer to WAV format
 */
function audioBufferToWav(buffer) {
    const length = buffer.length;
    const sampleRate = buffer.sampleRate;
    const arrayBuffer = new ArrayBuffer(44 + length * 2);
    const view = new DataView(arrayBuffer);
    const channelData = buffer.getChannelData(0);
    
    // WAV header
    const writeString = (offset, string) => {
        for (let i = 0; i < string.length; i++) {
            view.setUint8(offset + i, string.charCodeAt(i));
        }
    };
    
    writeString(0, 'RIFF');
    view.setUint32(4, 36 + length * 2, true);
    writeString(8, 'WAVE');
    writeString(12, 'fmt ');
    view.setUint32(16, 16, true);
    view.setUint16(20, 1, true);
    view.setUint16(22, 1, true);
    view.setUint32(24, sampleRate, true);
    view.setUint32(28, sampleRate * 2, true);
    view.setUint16(32, 2, true);
    view.setUint16(34, 16, true);
    writeString(36, 'data');
    view.setUint32(40, length * 2, true);
    
    // Convert float samples to 16-bit PCM
    let offset = 44;
    for (let i = 0; i < length; i++) {
        const sample = Math.max(-1, Math.min(1, channelData[i]));
        view.setInt16(offset, sample * 0x7FFF, true);
        offset += 2;
    }
    
    return arrayBuffer;
}

/**
 * Download audio file
 */
function downloadAudio(arrayBuffer, filename) {
    const blob = new Blob([arrayBuffer], { type: 'audio/wav' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

/**
 * Generate and download all audio files
 */
async function generateAllAudioFiles() {
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    
    for (const [soundType, config] of Object.entries(audioConfigs)) {
        console.log(`Generating ${soundType}...`);
        const buffer = generateAudioBuffer(audioContext, config);
        const wavData = audioBufferToWav(buffer);
        downloadAudio(wavData, `${soundType}.wav`);
        
        // Small delay between downloads
        await new Promise(resolve => setTimeout(resolve, 500));
    }
    
    console.log('All audio files generated!');
}

// Export for use in browser console or as module
if (typeof window !== 'undefined') {
    window.generateAllAudioFiles = generateAllAudioFiles;
    window.audioConfigs = audioConfigs;
    window.generateAudioBuffer = generateAudioBuffer;
    window.audioBufferToWav = audioBufferToWav;
    window.downloadAudio = downloadAudio;
}

console.log('Audio generator loaded. Run generateAllAudioFiles() to create all sound files.');
